/**
 *  基础方块类
 */

package cn.com.ldns.opentetris.shape;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

import javax.microedition.khronos.opengles.GL10;

import cn.com.ldns.opentetris.common.CodeUtil;
import cn.com.ldns.opentetris.common.FloatUtil;
import cn.com.ldns.opentetris.shape.model.Acceleration;
import cn.com.ldns.opentetris.shape.model.Position;
import cn.com.ldns.opentetris.shape.model.Rotate;
import cn.com.ldns.opentetris.shape.model.RotateAcce;

public abstract class BaseBox {
	
	protected short state =  CodeUtil.STATIC_1;
	protected Position[] positions;
	private List<Cube> cubes =new LinkedList<Cube>(); 
	private Acceleration acceleration;
	private RotateAcce rotateAcce;
	private Rotate rotate;
	private String boxId;
	private int textureId = -1; 
	
	/**
	 * 构造函数
	 */	
	public BaseBox(Position[] positions){
		this.boxId = UUID.randomUUID().toString();
		this.positions = positions;
		for(int i=0;i<positions.length;i++)
		{
			Cube cube = new Cube();
			cube.setPosition(positions[i]);
			cubes.add(cube);
		}
	}
	
	public void draw(GL10 gl){
		for(int i=0;i<cubes.size();i++)
		{
			Cube cube = cubes.get(i);
			cube.setPosition(positions[i]);
			
			if(acceleration !=null) 
				cube.setAcceleration(acceleration);
			
			if(rotateAcce !=null) 
				cube.setRotateAcce(rotateAcce);
			
			if(rotate !=null) 
				cube.setRotate(rotate);
			
			gl.glLoadIdentity();
			gl.glTranslatef(0, 0, -10);
			if(textureId != -1)
				cube.setTexture(textureId, Cube.textureCoords);
			cube.draw(gl);
		}
	}
	
	public void changeState(){
		Position old = positions[0];
		state++;
		
		if(state > CodeUtil.STATIC_4)
			state = CodeUtil.STATIC_1;
		
		initBoxPosition();
		
		Position vertor = new Position(
				FloatUtil.valueOf(old.getX() - positions[0].getX()),
				FloatUtil.valueOf(old.getY() - positions[0].getY()),
				FloatUtil.valueOf(old.getZ() - positions[0].getZ()));
		
		moveBox(vertor);
	}
	
	protected abstract void initBoxPosition();
	
	public Position getBoxPosition(){
		return positions[0];
	}
	
	public void moveBox(Position vetor ){
		for(int i=0;i<positions.length;i++)
		{
			positions[i].setX(FloatUtil.valueOf(positions[i].getX() + vetor.getX()));
			positions[i].setY(FloatUtil.valueOf(positions[i].getY() + vetor.getY()));
			positions[i].setZ(FloatUtil.valueOf(positions[i].getZ() + vetor.getZ()));
		}
	}
	
	public void stopBox() {
		this.acceleration = null;
		for (Cube c : cubes) {
			c.setAcceleration(null);
		}
	}
	
	public void setBoxTexture(int textures ){
		this.textureId = textures;
	}
	
	public void setBoxAcceleration(Acceleration acceleration){
		this.acceleration = acceleration;
	};
	
	public void setBoxRotateAcce(RotateAcce rotateAcce){
		this.rotateAcce = rotateAcce;
	};
	
	public void setBoxRotate(Rotate rotate){
		this.rotate = rotate;
	};
	
	public short getBoxType() {
		if (this instanceof BoxI) {
			return CodeUtil.SHAPE_I;
		} else if (this instanceof BoxJ) {
			return CodeUtil.SHAPE_J;
		} else if (this instanceof BoxL) {
			return CodeUtil.SHAPE_L;
		} else if (this instanceof BoxO) {
			return CodeUtil.SHAPE_O;
		} else if (this instanceof BoxS) {
			return CodeUtil.SHAPE_S;
		} else if (this instanceof BoxT) {
			return CodeUtil.SHAPE_T;
		} else if (this instanceof BoxZ) {
			return CodeUtil.SHAPE_Z;
		}
		return 0;
	}
	
	public short getState() {
		return this.state;
	}
	

	public Position[] getPositions() {
		return this.positions;
	}
	
	public String getBoxId() {
		return this.boxId;
	}
	
	
	public List<Cube> getCubes() {
		return this.cubes;
	}
}
